﻿#region Using Directives

using System.Drawing;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;

using GalaSoft.MvvmLight;

using Scripni.Chess.Core.BoardModels;
using Scripni.Chess.Core.Pieces;

#endregion

namespace Scripni.Chess.UI.ViewModels
{
    /// <summary>
    /// Represents a chess board square.
    /// </summary>
    public class BoardSquareViewModel : ViewModelBase
    {
        #region Constructors

        /// <summary>
        /// Creates a new instance of the <see cref="BoardSquareViewModel"/> class.
        /// </summary>
        /// <param name="position">The position on the chess board.</param>
        public BoardSquareViewModel(BoardPosition position)
        {
            this.position = position;
            this.color = GetColorFromPosition(position);
        }

        private static SquareColor GetColorFromPosition(BoardPosition position)
        {
            return (position.Column + position.Row) % 2 == 0
                       ? SquareColor.Dark
                       : SquareColor.Light;
        }

        private void UpdateImage(Piece newPiece)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                Icon icon = ResourceManager.Instance.GetPieceIcon(newPiece);
                if (icon != null)
                {
                    icon.Save(stream);
                    stream.Seek(0, SeekOrigin.Begin);
                    Image = new TransformedBitmap(
                        BitmapFrame.Create(stream),
                        new ScaleTransform(0.5, 0.5));
                }
                else
                {
                    Image = null;
                }
            }
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets the color of the chess square.
        /// </summary>
        public SquareColor Color
        {
            get
            {
                return this.color;
            }
        }

        private readonly BoardPosition position;

        public BoardPosition Position
        {
            get
            {
                return this.position;
            }
        }

        private Piece piece;

        /// <summary>
        /// Gets or sets the chess piece associated to the position.
        /// </summary>
        public Piece Piece
        {
            get
            {
                return this.piece;
            }
            set
            {
                this.piece = value;
                RaisePropertyChanged(() => Piece);
                UpdateImage(value);
            }
        }

        /// <summary>
        /// Gets the image of the chess piece on the current square (if any).
        /// </summary>
        public ImageSource Image
        {
            get
            {
                return this.image;
            }
            private set
            {
                this.image = value;
                RaisePropertyChanged(() => Image);
            }
        }

        #endregion

        #region Constants and Fields

        private readonly SquareColor color;

        private ImageSource image;

        #endregion
    }
}